package cn.cttic.link.dubbo;

import cn.cttic.base.api.RemoteBaseDeviceInfoService;
import cn.cttic.base.api.domain.BaseDeviceInfo;
import cn.cttic.base.api.domain.bo.BaseDeviceInfoBo;
import cn.cttic.base.api.domain.vo.BaseDeviceInfoVo;
import cn.cttic.base.api.domain.vo.ThirdDeviceInfoVo;
import cn.cttic.common.core.constant.CacheNames;
import cn.cttic.common.core.exception.link.LinkException;
import cn.cttic.common.core.utils.BeanCopyUtils;
import cn.cttic.common.redis.utils.CacheUtils;
import cn.cttic.common.redis.utils.RedisUtils;
import cn.cttic.link.api.RemoteThirdDistributeService;
import cn.cttic.link.api.domain.bo.BaseThirdInterfaceBo;
import cn.cttic.link.api.domain.vo.BaseThirdInterfaceConfigVo;
import cn.cttic.link.api.domain.vo.DistributeDevicePosisitionVo;
import cn.cttic.link.api.domain.vo.GisTimePosistionVo;
import cn.cttic.link.api.domain.vo.ThirdDistributeR;
import cn.cttic.link.api.enums.ThirdInterfaceType;
import cn.cttic.link.service.IBaseThirdInterfaceConfigService;
import cn.cttic.link.service.IBaseThirdInterfaceService;
import cn.cttic.link.util.HttpClientUtil;
import cn.cttic.order.api.RemoteInstallOrderService;
import cn.cttic.system.api.RemoteConfigService;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Pattern;

@Service
@Slf4j
@RequiredArgsConstructor
@DubboService
public class RemoteThirdDistributeServiceImpl implements RemoteThirdDistributeService {

    private final IBaseThirdInterfaceConfigService baseThirdInterfaceConfigService;

    private final IBaseThirdInterfaceService thirdInterfaceService;

    @DubboReference
    private RemoteBaseDeviceInfoService remoteBaseDeviceInfoService;

    @DubboReference
    private RemoteInstallOrderService remoteInstallOrderService;

    @DubboReference
    private RemoteConfigService remoteConfigService;

    /**
     * 检测终端信息
     *
     * @param imei IMEI 号码
     * @return 结果
     * @data {"code":200,"msg":null,"data":{"latitude":"0","longitude":"0","sendTime":""}}
     */
    @Override
    public GisTimePosistionVo checkTerminalInfo(String orderId, String imei) {

        try {
            log.info("[发行接口][检测终端信息][开始]");
            BaseThirdInterfaceConfigVo config = baseThirdInterfaceConfigService.getInterfaceConfig(ThirdInterfaceType.DISTRIBUTE_CHECK_TERMINAL.getValue());

            String url = config.getAccessUrl();
            url += "/" + imei;
            log.info("[发行接口][检测终端信息][请求地址]: {}", url);
            String result = HttpClientUtil.get(url);
            log.info("[发行接口][检测终端信息][返回内容]: {}", result);

            BaseThirdInterfaceBo interfaceBo = new BaseThirdInterfaceBo();
            interfaceBo.setBusinessId(orderId);
            interfaceBo.setInterfaceType(ThirdInterfaceType.DISTRIBUTE_CHECK_TERMINAL.getValue());
            interfaceBo.setAccessUrl(url);
            interfaceBo.setRequestType("GET");
            interfaceBo.setRequestBody("");
            interfaceBo.setResponseBody(result);

            if (!thirdInterfaceService.insertByBo(interfaceBo)) {
                throw new LinkException("录入接口数据失败");
            }
            log.info("[发行接口][检测终端信息][保存记录完成]");

            try {
                remoteInstallOrderService.deviceOnline(
                    imei,
                    LocalDateTime.now(),
                    interfaceBo.getId()
                );
                log.info("[发行接口][检测终端信息][上线完成]");
            } catch (Exception e) {
                log.error("[发行接口][检测终端信息][上线异常]", e);
            }

            ThirdDistributeR<DistributeDevicePosisitionVo> r = JSON.parseObject(result, new TypeReference<ThirdDistributeR<DistributeDevicePosisitionVo>>() {});
            if (r.getCode() == ThirdDistributeR.SUCCESS) {
                if (r.getData() == null) {
                    GisTimePosistionVo gisTimePosistionVo = new GisTimePosistionVo();
                    gisTimePosistionVo.setLatitude(new BigDecimal(1));
                    gisTimePosistionVo.setLongitude(new BigDecimal(1));
                    gisTimePosistionVo.setSendTime(LocalDateTime.parse("1998-01-01 00:00:00.000", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
                    return gisTimePosistionVo;
                } else {
                    DistributeDevicePosisitionVo vo = r.getData();
                    interfaceBo.setResponseData(JSON.toJSONString(vo));
                    if (!thirdInterfaceService.updateByBo(interfaceBo)) {
                        log.error("[发行接口][查询终端][更新三方记录失败] {}", interfaceBo);
                        throw new LinkException("更新三方记录失败");
                    }
                    GisTimePosistionVo gisTimePosistionVo = new GisTimePosistionVo();
                    if (StrUtil.isNotBlank(vo.getSendTime())) {
                        gisTimePosistionVo.setLatitude(new BigDecimal(vo.getLatitude()));
                    } else {
                        gisTimePosistionVo.setLatitude(new BigDecimal(1));
                    }
                    if (StrUtil.isNotBlank(vo.getLongitude())) {
                        gisTimePosistionVo.setLongitude(new BigDecimal(vo.getLongitude()));
                    } else {
                        gisTimePosistionVo.setLongitude(new BigDecimal(1));
                    }
                    if (StrUtil.isNotBlank(vo.getSendTime())) {
                        gisTimePosistionVo.setSendTime(LocalDateTime.parse(vo.getSendTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
                    } else {
                        gisTimePosistionVo.setSendTime(LocalDateTime.parse("1998-01-01 00:00:00.000", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
                    }
                    return gisTimePosistionVo;
                }
            } else {
                throw new LinkException(r.getMsg());
            }
        } catch (Exception e) {
            throw new LinkException(e.getMessage());
        }
    }

    /**
     * 终端注册
     *
     * @param imei IMEI 号码
     * @return 结果
     * @in_data {"cameraNumber": 2, "command": 1, "createTime": "2024-09-30 11:10:00", "terminalId": "14163324318"}
     */
    @Override
    public boolean registerTerminal(String orderId, String imei) {

        try {
            log.info("[发行接口][终端注册][开始]");
            BaseThirdInterfaceConfigVo config = baseThirdInterfaceConfigService.getInterfaceConfig(ThirdInterfaceType.DISTRIBUTE_REGISTER_TERMINAL.getValue());

            String url = config.getAccessUrl();
            log.info("[发行接口][终端注册][请求地址]: {}", url);

            Map<String, Object> params = new HashMap<>();
            params.put("terminalId", imei);
            params.put("cameraNumber", 2);
            params.put("createTime", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            params.put("command", 1);
            log.info("[发行接口][终端注册][请求内容]: {}", JSON.toJSONString(params));

            String result = HttpClientUtil.post(url, JSON.toJSONString(params), false);
            log.info("[发行接口][终端注册][返回内容]: {}", result);

            BaseThirdInterfaceBo interfaceBo = new BaseThirdInterfaceBo();
            interfaceBo.setBusinessId(orderId);
            interfaceBo.setInterfaceType(ThirdInterfaceType.DISTRIBUTE_REGISTER_TERMINAL.getValue());
            interfaceBo.setAccessUrl(url);
            interfaceBo.setRequestType("POST");
            interfaceBo.setRequestBody(JSON.toJSONString(params));
            interfaceBo.setResponseBody(result);

            if (!thirdInterfaceService.insertByBo(interfaceBo)) {
                throw new LinkException("录入接口数据失败");
            }
            log.info("[发行接口][终端注册][保存记录完成]");

            ThirdDistributeR r = JSON.parseObject(result, ThirdDistributeR.class);
            if (r.getCode() == ThirdDistributeR.SUCCESS) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            throw new LinkException(e.getMessage());
        }
    }

    /**
     * 查询终端
     *
     * @param imei IMEI 号码
     * @return 结果
     * @in_data {"cameraNumber": 2, "command": 1, "createTime": "2024-09-30 11:10:00", "terminalId": "14163324318"}
     */
    @Override
    public boolean queryTerminal(String orderId, String imei) {

        try {
            log.info("[发行接口][查询终端][开始]");
            BaseThirdInterfaceConfigVo config = baseThirdInterfaceConfigService.getInterfaceConfig(ThirdInterfaceType.DISTRIBUTE_QUERY_TERMINAL.getValue());

            String url = config.getAccessUrl();
            url += "/" + imei;
            log.info("[发行接口][查询终端][请求地址]: {}", url);
            String result = HttpClientUtil.get(url);
            log.info("[发行接口][查询终端][返回内容]: {}", result);

            BaseThirdInterfaceBo interfaceBo = new BaseThirdInterfaceBo();
            interfaceBo.setBusinessId(orderId);
            interfaceBo.setInterfaceType(ThirdInterfaceType.DISTRIBUTE_QUERY_TERMINAL.getValue());
            interfaceBo.setAccessUrl(url);
            interfaceBo.setRequestParam(imei);
            interfaceBo.setRequestType("GET");
            interfaceBo.setRequestBody("");
            interfaceBo.setResponseBody(result);

            if (!thirdInterfaceService.insertByBo(interfaceBo)) {
                throw new LinkException("录入接口数据失败");
            }
            log.info("[发行接口][查询终端][保存记录完成]");
            String ignoreQueryTerminalVal = remoteConfigService.selectConfig("sys.queryTerminal.ignore");
            boolean ignoreQueryTerminal = true;
            if (StrUtil.isNotBlank(ignoreQueryTerminalVal)) {
                ignoreQueryTerminal = ignoreQueryTerminalVal.toLowerCase().equals("true") || ignoreQueryTerminalVal.toLowerCase().equals("yes");
            }

            ThirdDistributeR<ThirdDeviceInfoVo> r = JSON.parseObject(result, new TypeReference<ThirdDistributeR<ThirdDeviceInfoVo>>() {});
            if (r.isSuccess() || r.getCode() == ThirdDistributeR.SUCCESS) {
                if (r.getData() == null) {
                    log.warn("[发行接口][查询终端][设备 {} 查询未返回设备信息]", imei);
                    if (ignoreQueryTerminal) {
                        return true;
                    } else {
                        throw new LinkException("没有返回数据");
                    }
                }
                ThirdDeviceInfoVo vo = r.getData();
                BaseDeviceInfoBo baseDeviceInfoBo = BeanCopyUtils.copy(vo, BaseDeviceInfoBo.class);
                baseDeviceInfoBo.setInstallOrderId(orderId);
                interfaceBo.setResponseData(JSON.toJSONString(baseDeviceInfoBo));
                if (!thirdInterfaceService.updateByBo(interfaceBo)) {
                    log.error("[发行接口][查询终端][更新三方记录失败] {}", interfaceBo);
                    if (ignoreQueryTerminal) {
                        return true;
                    } else {
                        throw new LinkException("更新三方记录失败");
                    }
                }

                // 记录设备信息------
                BaseDeviceInfoVo deviceInfoVo = remoteBaseDeviceInfoService.addBaseDeviceInfo(baseDeviceInfoBo);
                if (deviceInfoVo == null) {
                    log.error("[发行接口][查询终端][记录设备信息失败] {}", deviceInfoVo);
                    if (ignoreQueryTerminal) {
                        return true;
                    } else {
                        throw new LinkException("记录设备信息失败");
                    }
                }

                if (StrUtil.isNotBlank(vo.getStockStatus())) {
                    if (vo.getStockStatus().equals("2")) {
                        log.info("[发行接口][查询终端][设备 {} 已出库]", vo.getTerminalImei());
                        return true;
                    } else {
                        log.warn("[发行接口][查询终端][设备 {} 出库状态 {}]", vo.getTerminalImei(), vo.getStockStatus());
                        if (ignoreQueryTerminal) {

                            if (vo.getIsUse() != null && vo.getIsUse().equals("0")) {
                                return true;
                            } else if (vo.getIsUse() == null) {
                                throw new LinkException("设备占用状态不正确");
                            } else if (vo.getIsUse() == null) {
                                throw new LinkException("设备被占用");
                            }
                        } else {
                            throw new LinkException("设备出库状态不正确");
                        }
//                        return false;
                    }
                } else {
                    log.warn("[发行接口][查询终端][设备 {} 没有出库状态]", vo.getTerminalImei());
                    if (ignoreQueryTerminal) {
                        return true;
                    } else {
                        throw new LinkException("没有出库状态");
                    }
//                    return false;
                }
            } else {
                log.warn("[发行接口][查询终端][设备 {} 查询失败]", imei);
                throw new LinkException("查询设备信息失败");
//                return false;
            }
            return true;
        } catch (Exception e) {
            throw new LinkException(e.getMessage());
        }
    }

    /**
     * 终端占用
     *
     * @param imei IMEI 号码
     * @return 结果
     */
    @Override
    public boolean takeUpTerminal(String orderId, String imei) {
        imei = StrUtil.padPre(imei, 15, '0');
        try {
            log.info("[发行接口][终端占用][开始]");
            BaseThirdInterfaceConfigVo config = baseThirdInterfaceConfigService.getInterfaceConfig(ThirdInterfaceType.DISTRIBUTE_TAKEUP_TERMINAL.getValue());

            String url = config.getAccessUrl();
            url += "/" + imei;
            log.info("[发行接口][终端占用][请求地址]: {}", url);
            String result = HttpClientUtil.get(url);
            log.info("[发行接口][终端占用][返回内容]: {}", result);

            BaseThirdInterfaceBo interfaceBo = new BaseThirdInterfaceBo();
            interfaceBo.setBusinessId(orderId);
            interfaceBo.setInterfaceType(ThirdInterfaceType.DISTRIBUTE_TAKEUP_TERMINAL.getValue());
            interfaceBo.setAccessUrl(url);
            interfaceBo.setRequestType("GET");
            interfaceBo.setRequestBody("");
            interfaceBo.setResponseBody(result);

            if (!thirdInterfaceService.insertByBo(interfaceBo)) {
                throw new LinkException("录入接口数据失败");
            }
            log.info("[发行接口][同步备案数据][保存记录完成]");

            ThirdDistributeR r = JSON.parseObject(result, ThirdDistributeR.class);
            if (r.getCode() == ThirdDistributeR.SUCCESS) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            throw new LinkException(e.getMessage());
        }
    }

    /**
     * 释放终端
     *
     * @param imei IMEI 号码
     * @return 结果
     */
    @Override
    public boolean releaseTerminal(String orderId, String imei) {

        imei = StrUtil.padPre(imei, 15, '0');

        try {
            log.info("[发行接口][释放终端][开始]");
            BaseThirdInterfaceConfigVo config = baseThirdInterfaceConfigService.getInterfaceConfig(ThirdInterfaceType.DISTRIBUTE_RELEASE_TERMINAL.getValue());

            String url = config.getAccessUrl();
            url += "/" + imei;
            log.info("[发行接口][释放终端][请求地址]: {}", url);
            String result = HttpClientUtil.get(url);
            log.info("[发行接口][释放终端][返回内容]: {}", result);

            BaseThirdInterfaceBo interfaceBo = new BaseThirdInterfaceBo();
            interfaceBo.setBusinessId(orderId);
            interfaceBo.setInterfaceType(ThirdInterfaceType.DISTRIBUTE_RELEASE_TERMINAL.getValue());
            interfaceBo.setAccessUrl(url);
            interfaceBo.setRequestType("GET");
            interfaceBo.setRequestBody("");
            interfaceBo.setResponseBody(result);

            if (!thirdInterfaceService.insertByBo(interfaceBo)) {
                throw new LinkException("录入接口数据失败");
            }
            log.info("[发行接口][释放终端][保存记录完成]");

            ThirdDistributeR r = JSON.parseObject(result, ThirdDistributeR.class);
            if (r.getCode() == ThirdDistributeR.SUCCESS) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            throw new LinkException(e.getMessage());
        }
    }


}
